#include <arpa/inet.h>
#include <errno.h>
#include <fcntl.h>
#include <net/if.h>
#include <netinet/ip.h>
#include <pcap.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>

#define MAXBUF 2048

uint8_t mac[6] = "";
#define MY_IP_ADDRESS "192.168.2.1"
int sockfd = 0;

void *pcap_recv_loop(void *arg) {
  int32_t ret = 0;
  pcap_t *handle = (pcap_t *)arg;
  struct pcap_pkthdr pkthdr;
  const uint8_t *packet;
  uint8_t readbuf[MAXBUF] = "";
  while (1) {
    packet = pcap_next(handle, &pkthdr);
    if (packet != NULL) {

      for (int i = 0; i < pkthdr.len; ++i) {
        printf("%02X ", packet[i]);
        if ((i + 1) % 16 == 0)
          printf("\n"); // 每行打印16个字节
      }
      printf("\n");
      // Check if the packet is incoming or outgoing
      if (memcmp(packet + 6, mac, sizeof(mac)) == 0) {
        printf("Outgoing packet: %02x:%02x:%02x:%02x:%02x:%02x -> "
               "%02x:%02x:%02x:%02x:%02x:%02x\n",
               *(packet), *(packet + 1), *(packet + 2), *(packet + 3),
               *(packet + 4), *(packet + 5), mac[0], mac[1], mac[2], mac[3],
               mac[4], mac[5]);
        int32_t ret = write(sockfd, packet, pkthdr.len);
        if (ret < 0) {
          perror("write");
          exit(errno);
        }
      } else if (memcmp(packet, mac, sizeof(mac)) == 0) {
        printf("InComing packet: %02x:%02x:%02x:%02x:%02x:%02x -> "
               "%02x:%02x:%02x:%02x:%02x:%02x\n",
               mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], *(packet),
               *(packet + 1), *(packet + 2), *(packet + 3), *(packet + 4),
               *(packet + 5));
      }
    }

    memset(readbuf, 0, MAXBUF);
    ret = read(sockfd, readbuf, MAXBUF);
    if (ret > 0) {
      // printf("read %d bytes\n", ret);
      // for (int i = 0; i < ret; ++i) {
      //     printf("%02X ", readbuf[i]);
      //     if ((i + 1) % 16 == 0)
      //     printf("\n"); // 每行打印16个字节
      // }
      // printf("\n");
      pcap_sendpacket(handle, readbuf, ret);
    }
  }
}

int main(int argc, char *argv[]) {
  char errbuff[PCAP_ERRBUF_SIZE];
  //    const char *dev = pcap_lookupdev(errbuff);
  int32_t ret = 0;
  struct sockaddr_in dest;
  struct ifreq ifr;
  char *iface = "eth2";
  char buffer[MAXBUF];
  if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
    perror("Socket");
    exit(errno);
  }

  // 初始化服务器端（对方）的地址和端口信息
  bzero(&dest, sizeof(dest));
  dest.sin_family = AF_INET;
  dest.sin_port = htons(6666);
  if (inet_aton("192.168.148.77", &(dest.sin_addr)) < 0) {
    perror("inet_aton");
    exit(errno);
  }
  int flags = fcntl(sockfd, F_GETFL, 0);
  if (flags == -1) {
    perror("fcntl");
    exit(errno);
  }
  if (fcntl(sockfd, F_SETFL, flags | O_NONBLOCK) == -1) {
    perror("fcntl");
    exit(errno);
  }
  ifr.ifr_addr.sa_family = AF_INET;
  strncpy(ifr.ifr_name, iface, IFNAMSIZ - 1);

  if (ioctl(sockfd, SIOCGIFHWADDR, &ifr) < 0) {
    perror("ioctl");
    return 1;
  }
  memcpy(mac, ifr.ifr_hwaddr.sa_data, 6);
  // 连接服务器
  ret = connect(sockfd, (struct sockaddr *)&dest, sizeof(dest));
  while (ret != 0) {
    if ((errno == EINPROGRESS) || (errno == EALREADY)) {
      ret = connect(sockfd, (struct sockaddr *)&dest, sizeof(dest));
      continue;
    }
    perror("Connect ");
    exit(errno);
  }
  const char *dev = "eth2";

  if (dev == NULL) {
    fprintf(stderr, "Couldn't find default device: %s\n", errbuff);
    return 1;
  }

  printf("Device: %s\n", dev);
  printf("MAC Address: %02x:%02x:%02x:%02x:%02x:%02x\n", mac[0], mac[1], mac[2],
         mac[3], mac[4], mac[5]);
  pcap_t *handle = pcap_open_live(dev, BUFSIZ, 1, 0, errbuff);
  if (handle == NULL) {
    fprintf(stderr, "Couldn't open device %s: %s\n", dev, errbuff);
    return 2;
  }

  printf("Listening on %s...\n", dev);

  pcap_recv_loop(handle);

  return 0;
}
